﻿@namespace BulmaRazor.Components
@inherits InputBase<string>
@inject BulmaRazorJsInterop JsInterop

<input id="@Id" @attributes="Attributes" @bind-value="ShowValue"
       class="@classes"/>

@code {

    [Parameter]
    public TagsInputOptions Options { get; set; }

    private string ShowValue
    {
        get { return Value; }
        set
        {
            Value = value;
            ValueChanged.InvokeAsync(Value).GetAwaiter().GetResult();
        }
    }

    [Parameter]
    public EventCallback<TagsInput> AfterAdd { get; set; }

    [Parameter]
    public EventCallback<TagsInput> AfterRemove { get; set; }


    protected override void OnInitialized()
    {
        JSCallbackManager.AddEventHandler(Id, "after.add", new Func<Dictionary<string, object>, Task>((dict) => { return AfterAdd.InvokeAsync(this); }));
        JSCallbackManager.AddEventHandler(Id, "after.remove", new Func<Dictionary<string, object>, Task>((dict) =>
        {
    //ShowValue = dict["value"].ToString();
            return AfterRemove.InvokeAsync(this);
        }));
        JSCallbackManager.AddEventHandler(Id, "after.flush", new Func<Dictionary<string, object>, Task>((dict) =>
        {
    //ShowValue = "";
            return AfterRemove.InvokeAsync(this);
        }));
        base.OnInitialized();
    }

    protected override ValueTask DisposeAsync(bool disposing)
    {
        JSCallbackManager.DisposeObject(Id);
        return base.DisposeAsync(disposing);
    }

    private IJSObjectReference jsObj;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);
        if (firstRender)
        {
            jsObj = await JsInterop.TagsInputAttach("#" + Id, Options);
        }
    }

    #region js funs

    //Item to add
    public void Add(params string[] items)
    {
        jsObj?.InvokeVoidAsync("add", new object[] {items});
    }

    //Unselect the current selected tag
    public void ClearSelection()
    {
        jsObj?.InvokeVoidAsync("clearSelection");
    }

    //Shortcut to removeAll method
    public void Flush()
    {
        jsObj?.InvokeVoidAsync("flush");
    }

    //Sets focus on the input
    public void focus()
    {
        jsObj?.InvokeVoidAsync("focus");
    }

    //Check if given item is present
    public ValueTask<bool>? Has(string item)
    {
        return jsObj?.InvokeAsync<bool>("has", item);
    }

    //Get index of given item
    public ValueTask<int>? IndexOf(string item)
    {
        return jsObj?.InvokeAsync<int>("indexOf", item);
    }

    public ValueTask<string[]>? Items()
    {
        return jsObj?.InvokeAsync<string[]>("items");
    }

    public void Remove(string item)
    {
        jsObj?.InvokeVoidAsync("remove", item);
    }

    public void RemoveAll()
    {
        jsObj?.InvokeVoidAsync("removeAll");
    }

    public void RemoveAtIndex(int index, bool clearSelection = true)
    {
        jsObj?.InvokeVoidAsync("removeAtIndex", index, clearSelection);
    }

    //Select given item
    public void Select(params string[] items)
    {
        jsObj?.InvokeVoidAsync("select", new object[] {items});
    }

    public void SelectAtIndex(int index)
    {
        jsObj?.InvokeVoidAsync("selectAtIndex", index);
    }

    #endregion

}